// const { resourceUsage } = require("process");



class 读写类 {
    constructor(文件名) {
        // 文件名
        this.文件名 = 文件名;
        // 读取到的内容保存到内存中
        this.值 = undefined;
        // 初始化读取文件名
        文件名 != undefined ? this.读取(文件名) : false;
    }
    读取(文件名) {
        文件名 != undefined ? this.文件名 = 文件名 : false;
        let fs = require("fs");
        // 同步读取
        this.值 = fs.readFileSync(this.文件名).toString();
        return this.值;
    }
    // 值是字符串,对象只输出'[object Object]'字符串
    写入(值, 文件名) {
        let 文件名值 = 文件名 != undefined ? 文件名 : this.文件名;
        let fs = require("fs");
        try {
            fs.writeFileSync(文件名值, 值);
            this.文件名 = 文件名值;
            this.值 = 值;
            console.log('文件写入:成功!');
            return 1;
        } catch (err) {
            console.error('文件写入:失败!!', err);
            return 0;
        }

    }
    // 值是对象,如果是字符串,就输出"带双引号字符串",
    // 用于识别是否JSON(开头结尾都没有双引号的)
    // 自己写自己会出现{"文件名":"file1.txt","值":"{\"文件名\":\"file1.txt\",\"值\":\"\\\"{值:'www.baidu.comxxx'}\\\"\"}"}
    // 出现多个\\\反斜杠号.
    写入2jsonString(值, 文件名) {
        return this.写入(JSON.stringify(值), 文件名);

    }
    // 读写JSON文本变成对象(不含方法),值还是字符串
    读取2jsonParse(文件名) {
        let 值 = this.读取(文件名);
        return JSON.parse(值);
    }


}

// 读写=new 读写类('file1.txt');
// console.log(读写.读取());
// 读写=new 读写类();
// console.log(读写.读取('file1.txt'));
// 注意这里是TS目录不是CZF目录是vscode的工作目录开始的
// 读写=new 读写类('file1.txt');
// 读写.写入('www.baidu.com');
// 读写.读取('file2.txt')

// 读写=new 读写类('file1.txt');

// console.log(读写.写入2jsonString(读写))
// 读写 = new 读写类('file1.txt');
// 啊 = 读写.读取2jsonParse();


// console.log('-----');

class 时间类 {
    constructor(初始化时间) {
        this.时间组 = [];
        this.时间 = 0;
        this.原格时间 = 0;
        this.年 = 0;
        this.月 = 0;
        this.日 = 0;
        this.周几 = 0;
        this.时 = 0;
        this.分 = 0;
        this.秒 = 0;
        this.毫秒 = 0;
        this.设置 = {
            timeZone: 'Asia/Shanghai',
            hour12: false,
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit',
            second: '2-digit',
            fractionalSecondDigits: 3,
        }
        // 初始化
        初始化时间 != undefined ? this.获取时间(初始化时间) : this.获取时间();

    }
    获取时间(时间) {
        if (时间 == undefined) {
            this.原格时间 = new Date();
        } else {
            this.原格时间 = new Date(时间);
        }
        this.时间 = this.原格时间.toLocaleString(this.设置, this.设置);
        this.年 = this.原格时间.getFullYear();
        this.月 = this.原格时间.getMonth() + 1;
        this.日 = this.原格时间.getDate();
        this.周几 = this.原格时间.getDay();
        this.时 = this.原格时间.getHours();
        this.分 = this.原格时间.getMinutes();
        this.秒 = this.原格时间.getSeconds();
        this.毫秒 = this.原格时间.getUTCMilliseconds();
        this.时间组 = [this.年, this.月, this.日, this.周几, this.时, this.分, this.秒, this.毫秒];
        return this.时间;
    }
    年差(新时间, 旧时间) {
        let 新期 = new 时间类(新时间);
        let 旧期 = new 时间类(旧时间);
        let 差 = (新期.年) - (旧期.年);
        return 差;

    }
    月差(新时间, 旧时间) {
        let 新期 = new 时间类(新时间);
        let 旧期 = new 时间类(旧时间);
        let 差 = (新期.年 * 12 + 新期.月) - (旧期.年 * 12 + 旧期.月);
        return 差;
    }
    月天数(时间) {
        let 月天数时间 = 时间 != undefined ? 时间 : this.时间;
        let 时间值 = new 时间类(月天数时间);
        return new Date(时间值.年, 时间值.月, 0).getDate();
    }
    追加月数(月数) {
        // 月数= -2 (-1 减一个月)(-0 0 当前月),(1 加一个月) 2 都是可以的
        let 追月数 = 月数 != undefined ? 月数 : 1;
        let 年 = this.年;
        let 月 = this.月;
        let 日 = this.日;
        let 时 = this.时;
        let 分 = this.分;
        let 秒 = this.秒;
        let 毫秒 = this.毫秒;
        月 += 追月数;
        年 += Math.floor(月 / 12);
        月 = 月 % 12;
        let 新日期日数 = new Date(年, 月, 0).getDate();
        // 日=日>新日期日数?新日期日数:日;
        日 = Math.abs(新日期日数 - 日) < 4 ? 新日期日数 : 日;
        let 新日期 = new Date(年, 月 - 1, 日, 时, 分, 秒, 毫秒);
        this.获取时间(新日期);
        console.log(this.时间);
        return this.时间;
    }
    static 时间(时间) {
        let 时间值 = new 时间类(时间 != undefined ? 时间 : undefined);
        return 时间值.时间;
    }
    static 追加月数(月数, 时间) {
        let 时间值 = new 时间类(时间 != undefined ? 时间 : undefined);
        let 月数时间值 = 时间值.追加月数(月数);
        return 月数时间值;
    }

}

// 测试=new 时间类();
// // 测试.获取时间();
// // console.log('时间组:',测试.时间组);
// // console.log('年差',测试.年差('2024/12/16 23:14:14','2020/12/16 23:14:14'));
// // console.log('月差',测试.月差('2024/12/16 23:14:14','2020/10/16 23:14:14'));
// // console.log('月天数',测试.月天数('2024/10/16 23:14:14'));
// // 测试.追加月数();
// // 测试.追加月数(1);
// // 测试.追加月数(12);
// // console.log('--------');
// // 测试.获取时间('2024/12/31 23:14:14')
// // 测试.追加月数();
// // 测试.追加月数(1);
// // 测试.追加月数(1);
// // 测试.追加月数(2);
// // 测试.追加月数(12);
// // console.log('--------');
// 测试.获取时间('2024/12/1 23:14:14')
// 测试.获取时间('2024/12/15 23:14:14')
// // 测试.获取时间('2024/12/27 23:14:14')
// // 测试.获取时间('2024/12/28 23:14:14')
// // 测试.获取时间('2024/12/29 23:14:14')
// // 测试.获取时间('2024/12/30 23:14:14')
// // 测试.获取时间('2024/12/31 23:14:14')
// 测试.追加月数();
// 测试.追加月数(1);
// 测试.追加月数(1);
// 测试.追加月数(2);
// 测试.追加月数(12);
// 测试.追加月数(0);
// 测试.追加月数(-0);
// 测试.追加月数(-1);
// 测试.追加月数(-2);
// 测试.追加月数(-3);
// 测试.获取时间('2024/12/31 23:14:14');


// console.log('');

class 记录类 {
    constructor() {

        this.房间记录表 = [];
        this.出租房记录表 = [];
        this.len = 0;


        // this.总营业=new 营业类();
        // this.房间表=[];
        // this.水表表=[];
        // this.电表表=[];
        // this.住户表=[];
    }
    房间记录(操作人员, 操作标记, 房间表, 水表表, 电表表, 住户表) {
        // 完成-需要重 写代码
        let 时间值 = new 时间类();
        let 操作时间 = 时间值.时间();
        let 新操作记录 = [操作人员, 操作标记, 操作时间.时间, 房间表, 水表表, 电表表, 住户表]
        this.房间记录表.push(新操作记录);
        this.len++;
    }
    查看房间记录(下标号) {
        console.log(this.房间记录表[下标号]);
    }
    查看房间号记录(房号) {
        let 房间号记录集 = [];
        for (var i = 0; i < this.len; i++) {
            if (this.房间记录表[i][3].房号 == 房号) {
                房间号记录集.push(i);
            }
        }
        if (房间号记录集.length > 0) {
            console.log('找到如下记录:', 房号);
            console.log(房间号记录集);
        } else {
            console.log('没有找到', 房号);
        }
    }
}

class 营业类 {
    constructor(营业额, 支出额, 盈利额) {
        this.营业额 = 营业额 != undefined ? 营业额 : 0;
        this.支出额 = 支出额 != undefined ? 支出额 : 0;
        this.盈利额 = 盈利额 != undefined ? 盈利额 : 0;
    }
    编辑(营业额, 支出额, 盈利额) {
        营业额 != undefined ? this.营业额 = 营业额 : '';
        支出额 != undefined ? this.支出额 = 支出额 : '';
        盈利额 != undefined ? this.盈利额 = 盈利额 : '';
    }
    营业了(收入, 支出) {
        收入 != undefined ? this.营业额 += 收入 : '';
        支出 != undefined ? this.支出额 += 支出 : '';
        this.盈利额 = this.营业额 - this.支出额;
    }
    支出了(支出, 收入) {
        this.营业了(收入, 支出);
    }
    读取(读取值) {
        this.营业额 = 读取值.营业额;
        this.支出额 = 读取值.支出额;
        this.盈利额 = 读取值.盈利额;
    }
}

class 房间类 {
    constructor(房号, 房间状态 = '空房', 房租 = 250, 押金 = 500, 入住时间, 到期时间) {
        this.房号 = 房号;
        this.房间状态 = 房间状态 != undefined ? 房间状态 : '空房';
        this.房租 = 房租 != undefined ? 房租 : 0;
        this.押金 = 押金 != undefined ? 押金 : 0;
        this.入住时间 = 入住时间 != undefined ? 入住时间 : 0;
        this.到期时间 = 到期时间 != undefined ? 到期时间 : 0;
    }
    读取(读取值) {
        this.房号 = 读取值.房号;
        this.房间状态 = 读取值.房间状态;
        this.房租 = 读取值.房租;
        this.押金 = 读取值.押金;
        this.入住时间 = 读取值.入住时间;
        this.到期时间 = 读取值.到期时间;
    }

    编辑房间(房号, 房间状态, 房租, 押金, 入住时间, 到期时间) {
        房号 != undefined ? this.房号 = 房号 : '';
        房间状态 != undefined ? this.房间状态 = 房间状态 : '';
        房租 != undefined ? this.房租 = 房租 : '';
        押金 != undefined ? this.押金 = 押金 : '';
        入住时间 != undefined ? this.入住时间 = 入住时间 : '';
        到期时间 != undefined ? this.到期时间 = 到期时间 : '';
    }

    到期时间追加月(月数) {
        let 时间值 = new 时间类(this.到期时间);
        if (月数 != undefined) {
            // 完成-需要重 写
            this.到期时间 = 时间值.追加月数(月数);
        } else {
            // 否则只加1个月
            this.到期时间 = 时间值.追加月数(1);
        }
    }

    计费(当前时间, 是否到期时间追加月) {
        let 房租值 = 0;
        let 时间值 = 0;
        let 欠交月差值 = 0;
        // 完成-需要重 写
        // 如果当前时间传入,计费到当前时间(全部)
        if (当前时间 != undefined) {
            时间值 = new 时间类(当前时间);
            欠交月差值 = 时间值.月差(时间值.时间, this.到期时间);
            房租值 = this.房租 * 欠交月差值;
        } else {
            // 否则计费只一个月
            欠交月差值 = 1;
            房租值 = this.房租 * 欠交月差值;
        }
        // 判断是否追加月
        if (是否到期时间追加月 == true) {
            this.到期时间追加月(欠交月差值);
        }
        // 返回,总房租价格
        return 房租值
    }


    退费(当前时间) {
        // 这里是测试,需要重写(已解决多个月的处理计算2025.2.11)
        // 退费日期按:到期月-当前月=月差
        // 需要判断是否交完房租,需要重写
        let 时间值 = new 时间类(当前时间);
        let 月差=时间值.月差(当前时间,this.到期时间);
        let 月差房费=月差*this.房租;
        console.log(`月差:${月差} 月差房费:${月差房费}`);
        let 当月天数 = 时间值.月天数();
        // 当月天数=30;
        let 按天价退 = this.房租 / 当月天数;
        let 剩余天数 = 当月天数 - 时间值.日;
        let 退费价 = (按天价退 * 剩余天数) + this.押金-月差房费;
        // console.log("当月天数:(按天价退*剩余天数)+this.押金", 当月天数, 按天价退, 剩余天数, 退费价);
        console.log(`按天价退${按天价退}:房租/单月天数=${this.房租}/${当月天数}`);
        console.log(`剩余天数${剩余天数}:${当月天数} - ${时间值.日}`);
        console.log(`退费价${退费价}:(${按天价退} * ${剩余天数}) + ${this.押金}`);
        return 退费价;
    }
}

class 表类 {
    constructor(旧值, 新值, 单价) {
        this.旧值 = 旧值 != undefined ? 旧值 : 0;
        this.新值 = 新值 != undefined ? 新值 : 0;
        this.单价 = 单价 != undefined ? 单价 : 0;
    }

    编辑表(旧值, 新值, 单价) {
        旧值 != undefined ? this.旧值 = 旧值 : '';
        新值 != undefined ? this.新值 = 新值 : '';
        单价 != undefined ? this.单价 = 单价 : '';
    }

    计费(单价) {
        return 单价 != undefined ? (this.新值 - this.旧值) * 单价 : (this.新值 - this.旧值) * this.单价;
    }
    读取(读取值){
        this.旧值=读取值.旧值;
        this.新值=读取值.新值;
        this.单价=读取值.单价;
    }
}

class 住户类 {
    constructor(姓名, 手机, 身份证, 钥匙) {
        this.姓名 = 姓名 != undefined ? 姓名 : '';
        this.手机 = 手机 != undefined ? 手机 : '';
        this.身份证 = 身份证 != undefined ? 身份证 : '';
        this.钥匙 = 钥匙 != undefined ? 钥匙 : [];
    }

    编辑住户(姓名, 手机, 身份证, 钥匙) {
        姓名 != undefined ? this.姓名 = 姓名 : '';
        手机 != undefined ? this.手机 = 手机 : '';
        身份证 != undefined ? this.身份证 = 身份证 : '';
        钥匙 != undefined ? this.钥匙 = 钥匙 : '';
    }
    读取(读取值){
        this.姓名 =读取值.姓名 ;
        this.手机 =读取值.手机 ;
        this.身份证=读取值.身份证;
        this.钥匙 =读取值.钥匙 ;
    }
}

// class 出租房简单版 extends 房间类{
class 出租房简单版 extends 房间类 {
    constructor(管理者, 房号, 房间状态 = '空房', 房租 = 15000, 押金 = 30000, 入住时间, 到期时间) {
        super(房号, 房间状态, 房租, 押金, 入住时间, 到期时间);
        this.管理者 = 管理者 != undefined ? 管理者 : 'admin';
        this.总营业 = new 营业类();
        this.房间表 = [];
        this.水表表 = [];
        this.电表表 = [];
        this.住户表 = [];
        this.len = 0;
    }
    // 要一起添加,相同下标
    添加房间(房号, 房间状态, 房租, 押金, 入住时间, 到期时间) {
        this.房间表.push(new 房间类(房号, 房间状态, 房租, 押金, 入住时间, 到期时间));
        this.水表表.push(new 表类());
        this.电表表.push(new 表类());
        this.住户表.push(new 住户类());
        this.len++;
    }
    查找房号下标(房号) {
        for (var i = 0; i < this.len; i++) {
            if (this.房间表[i].房号 == 房号) {
                return i;
            }
        }
        return -1;
    }


    收房租(房号) {
        let lenx = this.查找房号下标(房号);
        let 房间费 = this.房间表[lenx].计费();
        let 水表费 = this.水表表[lenx].计费();
        let 电表费 = this.电表表[lenx].计费();
        let 房租费 = 房间费 + 水表费 + 电表费;
        console.log("房间费+水表费+电表费:", 房间费, 水表费, 电表费, '=', 房租费);
        this.总营业.营业了(房租费);
        return 房租费;
    }

    退租费(房号,退费时间) {
        let lenx = this.查找房号下标(房号);
        // 判断是否传入退费时间否则就按当前时间房间表来退费
        退费时间!=undefined?退费时间:时间类.时间();


        let 房间费 = this.房间表[lenx].退费(退费时间);
        let 水表费 = this.水表表[lenx].计费();
        let 电表费 = this.电表表[lenx].计费();
        let 房租费 = 房间费 - 水表费 - 电表费;
        console.log("房间费+水表费+电表费:", 房间费," - ", 水表费," - ",电表费, '=', 房租费);
        this.总营业.营业了(房租费);
        return 房租费;
    }



    删除房间(房号) {
        let lenx = this.查找房号下标(房号);
        if (lenx != -1) {
            this.房间表.splice(lenx, 1);
            this.水表表.splice(lenx, 1);
            this.电表表.splice(lenx, 1);
        }
    }

    保存(房号) {
        let 文件名值 = 房号 != undefined ? 房号 : this.房号;
        文件名值 += '.json';
        let 读写 = new 读写类();
        // 成功-保存this自己所有属性值(alt+shift+f格式化)
        return 读写.写入2jsonString(this, 文件名值);
    }

    读取(房号) {
        let 文件名值 = 房号 != undefined ? 房号 : this.房号;
        文件名值 += '.json';
        let 读写 = new 读写类();
        // 成功-保存this自己所有属性值(alt+shift+f格式化)
        let 读取 = 读写.读取2jsonParse(文件名值);
        this.房号 = 读取.房号;
        this.房间状态 = 读取.房间状态;
        this.房租 = 读取.房租;
        this.押金 = 读取.押金;
        this.入住时间 = 读取.入住时间;
        this.到期时间 = 读取.到期时间;
        this.管理者 = 读取.管理者;
        this.总营业.读取(读取.总营业);
        this.房间表=[];
        读取.房间表.forEach(房间 => {
            let 每个房间=new 房间类();
            每个房间.读取(房间);
            this.房间表.push(每个房间);
        });
        this.水表表=[];
        读取.水表表.forEach(水表=>{
            let 每个水表=new 表类();
            每个水表.读取(水表);
            this.水表表.push(每个水表);
        });
        this.电表表=[];
        读取.电表表.forEach(电表=>{
            let 每个电表=new 表类();
            每个电表.读取(电表);
            this.电表表.push(每个电表);
        });
        this.住户表=[];
        读取.住户表.forEach(住户=>{
            let 每个住户=new 住户类();
            每个住户.读取(住户);
            this.住户表.push(每个住户);
        });
        this.len = 读取.len;
    }


}


// 数据公寓 = new 出租房简单版('JPF', '数据公寓');
// // 数据公寓.管理者 = 'JianPF';
// // 公寓时间 = new 时间类(undefined);
// // 数据公寓.编辑房间(undefined, 房间状态 = '营业中', 15000, 30000, 公寓时间.时间, 公寓时间.追加月数(3 * 12));
// // console.log(时间类.时间());

// // 数据公寓.添加房间('505房');
// // 房间505下标 = 0;
// // 数据公寓.房间表[房间505下标].编辑房间(undefined, '空房', 251, 501)


// // 数据公寓.添加房间('501房', '空房间', 251, 501);

// // // 不合规,这里是没有营业操作的测试
// // 数据公寓.添加房间('502房', '已租', 252, 502, 时间类.时间(), 时间类.追加月数());

// // 数据公寓.添加房间('503房');
// // 数据公寓.添加房间('504房');
// // 数据公寓.添加房间('506房');

// // 房间表 = 数据公寓.房间表;
// // 水表 = 数据公寓.水表表;
// // 电表 = 数据公寓.电表表;
// // 住户表 = 数据公寓.住户表;

// // 房间号 = 房间表[0];
// // 水表号 = 水表[0];
// // 电表号 = 电表[0];
// // 住户号 = 住户表[0]

// // 房间号.编辑房间(undefined, '已租', 250, 500, 1, 2);
// // 水表号.编辑表(1, 22, 3);
// // 电表号.编辑表(100, 200, 1);

// // console.log(
// //     房间号.计费(),
// //     水表号.计费(),
// //     电表号.计费()
// // );

// // console.log(
// //     房间号.退费(),
// //     水表号.计费(),
// //     电表号.计费()
// // );

// // 数据公寓.收房租('505房');
// // 数据公寓.总营业.支出了(1000000);
// // i = 0;
// // while (i++ < 10) { 数据公寓.收房租('505房'); }

// // 读写 = new 读写类();
// // 读写.写入2jsonString(数据公寓, 'file1.txt');
// // 数据公寓.保存();
// 数据公寓.读取();
// console.log('.');


// 导出多个函数,属性:源方法
module.exports={
    读写类:读写类,
    时间类:时间类,
    记录类:记录类,
    营业类:营业类,
    房间类:房间类,
    表类:表类,
    住户类:住户类,
    出租房:出租房简单版
}